{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "0091cfc7-ee8b-4a45-b2d9-374aadd7dbdc",
   "metadata": {},
   "source": [
    "# How to Format Floats Within F-Strings in Python\n",
    "# Code And Solutions"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4e2cf3c9-8cae-4b77-ba34-0d7135f7f64c",
   "metadata": {},
   "source": [
    "In this notebook, you'll find all of the code and the solutions to the exercises found in the Real Python tutorial [How to Format Floats Within F-Strings in Python](https://realpython.com/how-to-python-f-string-format-float/)\n",
    "\n",
    "The code and solutions are presented here in the same order they appear in the tutorial."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "21d291b8-a14d-4a86-b194-c19a22828aff",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'One third, expressed as a float is: 0.3333333333333333'"
      ]
     },
     "execution_count": 1,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "f\"One third, expressed as a float is: {1 / 3}\""
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d556c48b-2da7-463f-9fa5-57d728b43d68",
   "metadata": {},
   "source": [
    "## How to Format and Round a Float Within a Python F-String"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "a4e674cd-cd30-4b6d-bffa-055d049773cf",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'One third, rounded to two decimal places is: 0.33'"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "f\"One third, rounded to two decimal places is: {1 / 3:.2f}\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "ea8f2614-69c9-4dcd-a689-621a1294cd7d",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'£1,000.00 + £200.00 = £1,200.00'"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "def total_price(cost):\n",
    "    return cost * 1.2\n",
    "\n",
    "\n",
    "cost_price = 1000\n",
    "tax = 0.2\n",
    "f\"£{1000:,.2f} + £{cost_price * tax:,.2f} = £{total_price(cost_price):,.2f}\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "5306e7b6-9684-4d38-8bc5-e7189039172f",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'Area= 327.0435934242156'"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import math\n",
    "\n",
    "f\"Area= {math.pi * 10.203**2}\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "041df382-60fa-4e33-9e72-93b266bb1ddb",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'Area = 327.04'"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "f\"Area = {math.pi * 10.203**2:,.5g}\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "877cbf09-c1cd-4388-afe8-370d2bafb62a",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'12.6%'"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "f\"{0.1256:.1%}\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "9645ef7f-4d5f-4ff1-b452-607b8e6e2593",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'50.00%'"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "f\"{0.5:.2%}\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "fcf2e778-3799-4a00-a5d2-10258f63ef13",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'300.00%'"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "f\"{3:.2%}\""
   ]
  },
  {
   "cell_type": "markdown",
   "id": "918139ba-3e38-464c-ba76-9b324cd17cc1",
   "metadata": {},
   "source": [
    "### Possible Solutions - Formatting Strings Neatly"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "81e89225-a477-4154-806f-2cf34a0138d9",
   "metadata": {},
   "source": [
    "**Task 1 - Possible Solution**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "02230a9e-74db-4de2-a7af-1058b06cdf4e",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'The number 64,723.4161, when rounded to two decimal places is 64_723.42.'"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "number = 64723.4161\n",
    "\n",
    "(\n",
    "    f\"The number {number:,.4f}, when rounded to two decimal places is {number:_.2f}.\"\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ef52991e-ff54-4c36-b671-7e0711e0cd78",
   "metadata": {},
   "source": [
    "This solution uses two format specifiers. The first displays the original number with a thousands separator (`,`) and `4` decimal places of precision, while the second displays it with the underscore separator (`_`) and rounded to `2` decimal places."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b89d4bc6-6e52-42ec-ba1d-0467bff7dd05",
   "metadata": {},
   "source": [
    "**Task 2 - Possible Solution**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "4eb49d91-8822-4049-83ed-ddb6ecb47c2c",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'3/8 as a percentage is 37.5%.'"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "numerator = 3\n",
    "denominator = 8\n",
    "(\n",
    "    f\"{numerator}/{denominator} as a percentage is {numerator / denominator:.1%}.\"\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "96f8419f-87f5-480b-aabc-0652e03d78a0",
   "metadata": {},
   "source": [
    "This time the solution uses two replacement fields to display the numbers in their original forms.  The answer is then calculated within a format specifier and displayed as a percentage to one decimal place using `.1%`."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2257ad8a-3ea1-4784-976e-c5bcd54ed718",
   "metadata": {},
   "source": [
    "**Task 3 - Possible Solution**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "1113acb7-8905-4c3d-a855-685946e0c795",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'The volume of a sphere with radius 2.34 meters is 53.671 meters cubed.'"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import math\n",
    "\n",
    "radius = 2.340\n",
    "(\n",
    "    f\"The volume of a sphere with radius {radius} meters \"\n",
    "    f\"is {4 / 3 * math.pi * radius**3:.5g} meters cubed.\"\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a8af107a-4962-452a-80ce-642d3bfa6c14",
   "metadata": {},
   "source": [
    "Here, the first replacement field displays the original radius while the format specifier within the second calculates and displays the result of the volume calculation to 5 significant figures. This precision was chosen because the original radius was defined with this amount of significant figures."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a481797e-528c-4635-9031-e36f08eab0aa",
   "metadata": {},
   "source": [
    "## Customizing the Width of Your Formatted Strings"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "3bb7e4c0-251d-4e52-bb54-8dfeb165f9b3",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(1) |12345.68|\n",
      "(2) |12345.68|\n",
      "(3) |12345.68|\n",
      "(4) |    12345.68|\n"
     ]
    }
   ],
   "source": [
    "sample = 12345.6789\n",
    "\n",
    "print(\n",
    "    f\"(1) |{sample:.2f}|\",\n",
    "    f\"(2) |{sample:1.2f}|\",\n",
    "    f\"(3) |{sample:8.2f}|\",\n",
    "    f\"(4) |{sample:12.2f}|\",\n",
    "    sep=\"\\n\",\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "0f87291d-140e-4644-a80f-92635ab7154f",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'|123.45    |'"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "f\"|{'123.45':10}|\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "67690568-4a7a-4fd9-82de-9984c3eb7b0b",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'|    123.45|'"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "f\"|{123.45:10}|\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "eb78dfcc-5593-4ace-bb63-a82a78ca3c5f",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(1) |12,345.68   |\n",
      "(2) |   12,345.68|\n",
      "(3) | 12,345.68  |\n"
     ]
    }
   ],
   "source": [
    "sample = 12345.6789\n",
    "\n",
    "print(\n",
    "    f\"(1) |{sample:<12,.2f}|\",\n",
    "    f\"(2) |{sample:>12,.2f}|\",\n",
    "    f\"(3) |{sample:^12,.2f}|\",\n",
    "    sep=\"\\n\",\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "4a62e015-4b28-47e5-878d-e78243d17ce9",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(1) |12345.68****|\n",
      "(2) |****12345.68|\n",
      "(3) |**12345.68**|\n"
     ]
    }
   ],
   "source": [
    "sample = 12345.6789\n",
    "\n",
    "print(\n",
    "    f\"(1) |{sample:*<12.2f}|\",\n",
    "    f\"(2) |{sample:*>12.2f}|\",\n",
    "    f\"(3) |{sample:*^12.2f}|\",\n",
    "    sep=\"\\n\",\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d75306bd-baa2-4c6d-90f9-eeef2e4addca",
   "metadata": {},
   "source": [
    "## Controlling the Placement of Number Signs"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "168c7684-0db6-45bf-b7aa-c62303007429",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(1) |  -12,345.68|\n",
      "(2) |  -12,345.68|\n",
      "(3) |  +12,345.68|\n"
     ]
    }
   ],
   "source": [
    "sample = -12345.68\n",
    "\n",
    "print(\n",
    "    f\"(1) |{sample:12,.2f}|\",\n",
    "    f\"(2) |{sample:+12,.2f}|\",\n",
    "    f\"(3) |{-sample:+12,.2f}|\",\n",
    "    sep=\"\\n\",\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "c9b22f0b-2108-4532-86dc-232879517f9d",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(1)           -0\n",
      "(2)         -0.0\n"
     ]
    }
   ],
   "source": [
    "result = (5 * 0) / (-4 + 2)\n",
    "\n",
    "print(\n",
    "    f\"(1) {result:12.1g}\",\n",
    "    f\"(2) {result:+12.1f}\",\n",
    "    sep=\"\\n\",\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "5138270b-9c35-492a-a911-11a497a49b59",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(1)            0\n",
      "(2)          0.0\n"
     ]
    }
   ],
   "source": [
    "print(\n",
    "    f\"(1) {result:z12.1g}\",\n",
    "    f\"(2) {result:z12.1f}\",\n",
    "    sep=\"\\n\",\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a4e85894-3386-48e8-9e16-938ad805853c",
   "metadata": {},
   "source": [
    "### Possible Solutions - More Challenging Formatting"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "28a07ae3-2155-444e-9b1b-00a93a22f353",
   "metadata": {},
   "source": [
    "**Task 4a - Possible Solution**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "id": "a750fe81-86b4-434e-b38a-8f8fd960c39d",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "|-12,345.68  |\n",
      "|+12,345.68  |\n"
     ]
    }
   ],
   "source": [
    "sample = -12345.6789\n",
    "\n",
    "print(\n",
    "    f\"|{sample:<+12,.2f}|\",\n",
    "    f\"|{-sample:<+12,.2f}|\",\n",
    "    sep=\"\\n\",\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ee286622-ab53-4eb1-8871-68c2c2094b1c",
   "metadata": {},
   "source": [
    "To display the number as required for task 4a, you use `<+12,.2f`. The less than symbol (`<`) causes a left-alignment while the plus symbol (`+`) makes sure a symbol is always displayed. The `12` and `2` define the width and precision, respectively, while the comma (`,`) adds a separator. Finally, the lowercase _`f`_ rounds the output to 2 decimal places."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4ea6057b-ecde-4df5-a0c4-c9a23925d217",
   "metadata": {},
   "source": [
    "**Task 4b - Possible Solution**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "id": "1a288a68-4a02-4d29-9768-50e550d4f38b",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "|-12,345.68  |\n",
      "| 12,345.68  |\n"
     ]
    }
   ],
   "source": [
    "print(\n",
    "    f\"|{sample:<12,.2f}|\",\n",
    "    f\"|{-sample:< 12,.2f}|\",\n",
    "    sep=\"\\n\",\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d424d3b3-5439-4ebc-8334-5c5c45c96082",
   "metadata": {},
   "source": [
    "To display the number as required for task 4b, you use `< 12,.2f`. By adding a single space between the less than symbol (`<`) and `12`, you still display negative numbers with the negative (`-`) symbol but use a space instead of a plus (`+`) for positive numbers."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "20b8d7a7-611a-44b3-9a7b-b60df462bae9",
   "metadata": {},
   "source": [
    "**Task 5 - Possible Solution**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "id": "0fbe9a31-67f6-4b42-9b0d-3a614304942e",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "By default, the result is displayed like this: 15\n",
      "However, some people love trailing decimal points like this: 15.\n"
     ]
    }
   ],
   "source": [
    "result = 5 * 3\n",
    "\n",
    "print(\n",
    "    f\"By default, the result is displayed like this: {result}\",\n",
    "    f\"However, some people love trailing decimal points like this: {result:#.0f}\",\n",
    "    sep=\"\\n\",\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1d5089ca-edc6-40f1-bc6f-1966064a410a",
   "metadata": {},
   "source": [
    "To display the number using its default settings, there is no need for any format specifier. All you need to do is encase it within `{result}`. To display a trailing decimal point, you include the hash (`#`) symbol within the format specifier as shown. If you did this, `f\"However, some people love trailing decimal points like this: {result:.0f}.\"`, the output is the same, but technically you have not done what was required.\n",
    "\n",
    "When you use the hash (`#`) symbol in a format specifier, you are displaying your number using its *alternate form*. While displaying trailing decimals is certainly one use, this alternate form also allows you to display [binary](https://en.wikipedia.org/wiki/Binary_number), [octal](https://en.wikipedia.org/wiki/Octal) and [hexadecimal](https://en.wikipedia.org/wiki/Hexadecimal) numbers with `0b`, `0o`, and `0x` prefixes, respectivley."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cc3f180d-2432-4c78-86f9-2cd6db929778",
   "metadata": {},
   "source": [
    "**Task 6 - Possible Solution**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "id": "bf2b1d9e-749d-4fd9-89c7-6083a6f53fdb",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "C12345600012.3400056.78\n"
     ]
    }
   ],
   "source": [
    "customer_id = \"C123456\"\n",
    "amount1 = 12.34\n",
    "amount2 = 56.78\n",
    "\n",
    "print(f\"{customer_id}{amount1:08.2f}{amount2:08.2f}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8e6ec1ae-e068-4780-bdf8-249913c700a3",
   "metadata": {},
   "source": [
    "The first replacement field displays the original `customer_id`. To achieve the desired format of each amount, you use `0>8.2f`. The `0` inserts the zero padding. Although you could have added the greater than symbol (`>`) to right-align your output, this is the default behavior for numbers and causes the padding to be placed to the left. As before, `8` is the width while `.2f` results in rounding to 2 decimal places."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "df060494-83e0-42cc-b61a-9ff2876b2a1c",
   "metadata": {},
   "source": [
    "## Rounding Scientific Notation and Complex Numbers"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "id": "5cb9ba3f-30a7-4ce2-a120-1408f2c2534d",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'1.23e+03'"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "f\"{1234.56789:.2e}\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "id": "3f6e8d8a-f7de-46e9-be27-39a3ff234343",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'1.234e-04'"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "f\"{0.00012345:.3e}\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "id": "186656c1-f34a-4250-ae44-d51c2313a386",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "The complex number (3.474+2.323j) is formed\n",
      "from the real part 3.47,\n",
      "the imaginary part 2.3,\n",
      "and is approximately 3+2j.\n"
     ]
    }
   ],
   "source": [
    "value = 3.474 + 2.323j\n",
    "print(\n",
    "    f\"The complex number {value} is formed\",\n",
    "    f\"from the real part {value.real:.2f},\",\n",
    "    f\"the imaginary part {value.imag:.1f},\",\n",
    "    f\"and is approximately {value:.0f}.\",\n",
    "    sep=\"\\n\",\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1c79d13a-0035-404c-8279-117cda0042c7",
   "metadata": {},
   "source": [
    "### Possible Solutions -  Formatting Scientific Notation and Complex Nmbers"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "65f6a469-455d-436d-887c-1bd0bb1f4f99",
   "metadata": {},
   "source": [
    "**Task 7 - Possible Solution**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "id": "a4eb1455-ee7c-45b1-bae0-c3652fc9e198",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "The real part is 1.36E+04 and the imaginary part 2.45E-02.\n"
     ]
    }
   ],
   "source": [
    "value = 13579 + 0.0245j\n",
    "print(\n",
    "    f\"The real part is {value.real:.2E} and the imaginary part {value.imag:.2E}.\"\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "80028996-b774-4d52-9968-e4e33ce27abc",
   "metadata": {},
   "source": [
    "To produce the required output, you can use `.2E` to round the output to two decimal places for each of the `.real` and `.imag` components and display them using scientific notation."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e4c89eac-4692-4ae1-bbf4-e7824b1d9531",
   "metadata": {},
   "source": [
    "## Using `decimal` Objects to Mitigate Floating Point Inaccuracies"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "id": "31fd604a-8b78-47dd-aad2-a1b67ddbdddb",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'3333333333333.3335'"
      ]
     },
     "execution_count": 28,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "f\"{(10000000000000 / 3)}\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "id": "64716c7e-7be2-48dc-9cc0-ff98809a9f74",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'3333333333334.0'"
      ]
     },
     "execution_count": 29,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "f\"{(10000000000000 / 3) + 0.6666}\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "id": "34086c6a-fa5e-4927-b415-9ecbc681143d",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'£0.30000000000000004'"
      ]
     },
     "execution_count": 30,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from decimal import Decimal as D\n",
    "from decimal import getcontext\n",
    "\n",
    "getcontext().prec = 4\n",
    "f\"£{float('0.1') + float('0.1') + float('0.1')}\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "id": "5bf86971-93e8-4c1f-a5ec-8b5689dfcc69",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'£0.3'"
      ]
     },
     "execution_count": 31,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "f\"£{D('0.1') + D('0.1') + D('0.1')}\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "id": "d5cf3d3b-9085-4570-94bc-e608897561fb",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'£0.30'"
      ]
     },
     "execution_count": 32,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "getcontext().prec = 4\n",
    "f\"£{D('0.10001') + D('0.20001'):.2f}\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "id": "8ad2ffd8-d1a9-4e03-b95f-c71c82f5b39a",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Decimal('0.1000000000000000055511151231257827021181583404541015625')"
      ]
     },
     "execution_count": 33,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "D(0.1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "id": "a719e5be-d251-4a0c-9089-c1b43d91a429",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Decimal('0.1000')"
      ]
     },
     "execution_count": 34,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "D(0.1) * D(1)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6ae57de8-5e07-4bf5-b906-fd8adc12281c",
   "metadata": {},
   "source": [
    "## Formatting Strings in Other Ways"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "id": "3b888654-4cf8-4543-889f-49f2b4d64cb9",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'  -123.46'"
      ]
     },
     "execution_count": 35,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "format(-123.4567, \"+9.2f\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "id": "21ccd2b7-ded5-46a9-a814-2e279019576f",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'  -123.46'"
      ]
     },
     "execution_count": 36,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "f\"{-123.456:+9.2f}\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "id": "a8c8697b-0492-45ce-b2d4-faf2abdd5745",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'12.50%'"
      ]
     },
     "execution_count": 37,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "format(0.125, \".2%\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "id": "08d84720-8519-4ca5-8667-7767d6407747",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'12.50%'"
      ]
     },
     "execution_count": 38,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "f\"{0.125:.2%}\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "id": "cd8e2704-6b55-4795-93e2-2a9e8f65cdd7",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'Opposite = 1.2, Adjacent = 5.68, Hypotenuse = 5.811'"
      ]
     },
     "execution_count": 39,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "opposite = 1.234\n",
    "adjacent = 5.678\n",
    "hypotenuse = (opposite**2 + adjacent**2) ** 0.5\n",
    "template = \"Opposite = {:0.1f}, Adjacent = {:0.2f}, Hypotenuse = {:0.3f}\"\n",
    "template.format(opposite, adjacent, hypotenuse)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "id": "c53f3044-2d35-4982-b6e1-e4058cdd4b8a",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'Opposite = 1.2, Adjacent = 5.68, Hypotenuse = 5.811'"
      ]
     },
     "execution_count": 40,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data = {\n",
    "    \"opposite\": 1.234,\n",
    "    \"adjacent\": 5.678,\n",
    "    \"hypotenuse\": (1.234**2 + 5.678**2) ** 0.5,\n",
    "}\n",
    "\n",
    "template = (\n",
    "    \"Opposite = {opposite:0.1f}, \"\n",
    "    \"Adjacent = {adjacent:0.2f}, \"\n",
    "    \"Hypotenuse = {hypotenuse:0.3f}\"\n",
    ")\n",
    "\n",
    "template.format(**data)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "id": "a2594f50-7881-4849-b587-2386d6027503",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "123.24  \n"
     ]
    }
   ],
   "source": [
    "num = \"{:{align}{width}.{precision}f}\"\n",
    "print(num.format(123.236, align=\"<\", width=8, precision=2))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "id": "3b298fc3-28e3-4f3f-8e51-0e1d4aee6345",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['**Python**', '**is**', '**cool**']"
      ]
     },
     "execution_count": 42,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "text = \"Python is cool\"\n",
    "padded_words = [\n",
    "    \"{word:*^{length}}\".format(word=word, length=len(word) + 4)\n",
    "    for word in text.split()\n",
    "]\n",
    "\n",
    "padded_words"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b398b4d7-0cf1-4af7-b12d-ff7690dbd0f1",
   "metadata": {},
   "source": [
    "### Possible Solutions -  String Formatting Challenges"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b843686b-6b6d-48e1-8d13-d8fa1426024f",
   "metadata": {},
   "source": [
    "**Task 8 - Possible Solution**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "id": "21254bfa-5218-4152-8fd9-e9474b73bd7a",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['**Python**', '**is**', '**cool**']"
      ]
     },
     "execution_count": 43,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "text = \"Python is cool\"\n",
    "padded_words = [\n",
    "    f\"{word:*^{len(word) + 4}}\" for word in \"Python is cool\".split()\n",
    "]\n",
    "padded_words"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "497c5965-f9df-4b81-af9f-43a4a38acf2f",
   "metadata": {},
   "source": [
    "This solution uses nested f-string replacement fields. The `{len(word) + 4}` replacement field calculates the display width and provides the precision to the format specifier. The format specifier also uses `*^` to center align the output and pad it with `*` symbols.\n",
    "\n",
    "Each string inside the original list is passed to the format specifier as its `word` varaiable for formatting. Each formatted version is then appended to the `padded_words` list."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1d2fd54a-55a3-405a-81e3-0feae317f9c1",
   "metadata": {},
   "source": [
    "**Task 9 - Possible Solution**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "id": "69d2a835-ca3a-4d64-a69a-6fa3019ed399",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['1234.5679', '123.457', '12.35', '1.2']"
      ]
     },
     "execution_count": 44,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "def make_string(num):\n",
    "    return f\"{num:.{len(str(num).split('.')[0])}f}\"\n",
    "\n",
    "\n",
    "numbers = [\n",
    "    1234.56789,\n",
    "    123.456789,\n",
    "    12.3456789,\n",
    "    1.23456789,\n",
    "]\n",
    "numbers_formatted = [make_string(number) for number in numbers]\n",
    "\n",
    "numbers_formatted"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e0abd724-fe6c-4479-b8eb-5b3e6783d6c5",
   "metadata": {},
   "source": [
    "This solution uses a custom `make_string()` function. The function converts each number into a `str` to allow you to split it into two components. When you call `.split(\".\")` on this string, a list is returned for each number containing the numbers before the decimal point and those after.\n",
    "\n",
    "The precision part of the format specifier is then calculated using Python's built-in `len()` function to count the number of characters before the decimal point. The remainder of the format specifier uses the comma (`,`) to produce a thousands separator and the `num` function parameter as its data.\n",
    "\n",
    "Each formatted number is then printed."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "75f65508-b156-4981-8749-7db165c988b3",
   "metadata": {},
   "source": [
    "## Formatting Numbers for International Use"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "id": "cfc33c97-6c29-41d1-9903-aea92c143670",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "('en_US', 'UTF-8')"
      ]
     },
     "execution_count": 45,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import locale\n",
    "\n",
    "locale.getlocale()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "id": "7675f5fb-f3de-400c-9166-ad9ebecd8781",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'-1234.57'"
      ]
     },
     "execution_count": 46,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "f\"{-1234.567:n}\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "id": "6e4aae01-d7eb-438b-a367-4e69f9e8c6a7",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'-1234.57'"
      ]
     },
     "execution_count": 47,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "f\"{-1234.567:.2f}\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "id": "74b72fba-a566-4e8d-ab73-d8a06d52b87d",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "USA uses 1,234.57 and -1,234.57\n",
      "Poland uses 1 234,57 and -1 234,57\n",
      "UK uses 1,234.57 and -1,234.57\n",
      "Czech Republic uses 1 234,57 and -1 234,57\n",
      "Korea uses 1,234.57 and -1,234.57\n",
      "Germany uses 1.234,57 and -1.234,57\n",
      "France uses 1 234,57 and -1 234,57\n"
     ]
    }
   ],
   "source": [
    "sample_locales = [\n",
    "    (\"USA\", \"en_US.UTF-8\"),\n",
    "    (\"Poland\", \"pl_PL.UTF-8\"),\n",
    "    (\"UK\", \"en_GB.UTF-8\"),\n",
    "    (\"Czech Republic\", \"cs_CZ.UTF-8\"),\n",
    "    (\"Korea\", \"ko_KR.UTF-8\"),\n",
    "    (\"Germany\", \"de_DE.UTF-8\"),\n",
    "    (\"France\", \"fr_FR.UTF-8\"),\n",
    "]\n",
    "\n",
    "for name, loc in sample_locales:\n",
    "    _ = locale.setlocale(category=locale.LC_ALL, locale=loc)\n",
    "    print(\n",
    "        f\"{name} uses\",\n",
    "        f\"{1234.567:n} and\",\n",
    "        f\"{-1234.567:n}\",\n",
    "    )"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "id": "80604884-9645-4332-8d80-2b4f9fbe916e",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "USA uses -->  -1.23e+05\n",
      "Poland uses -->  -1,23e+05\n",
      "UK uses -->  -1.23e+05\n",
      "Czech Republic uses -->  -1,23e+05\n",
      "Korea uses -->  -1.23e+05\n",
      "Germany uses -->  -1,23e+05\n",
      "France uses -->  -1,23e+05\n"
     ]
    }
   ],
   "source": [
    "for name, loc in sample_locales:\n",
    "    _ = locale.setlocale(category=locale.LC_ALL, locale=loc)\n",
    "    print(\n",
    "        f\"{name} uses --> {locale.format_string(f='%10.2e', val=-123456.789, grouping=True)}\"\n",
    "    )"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "id": "153e2705-06e2-4038-83fe-85a7b080a163",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "USA uses $123,456.79 and -$123,456.79\n",
      "Poland uses 123 456,79 zł and -123 456,79 zł\n",
      "UK uses £123,456.79 and -£123,456.79\n",
      "Czech Republic uses 123 456,79 Kč and -123 456,79 Kč\n",
      "Korea uses ₩123,457 and ₩123,457-\n",
      "Germany uses 123.456,79 € and -123.456,79 €\n",
      "France uses 123 456,79 € and -123 456,79 €\n"
     ]
    }
   ],
   "source": [
    "for name, loc in sample_locales:\n",
    "    _ = locale.setlocale(category=locale.LC_ALL, locale=loc)\n",
    "    print(\n",
    "        f\"{name} uses\",\n",
    "        f\"{(locale.currency(val=123456.789, grouping=True))} and\",\n",
    "        f\"{locale.currency(val=-123456.789, grouping=True)}\",\n",
    "    )"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
